#include "c_interface.h"
#include "../core/core.h"
#include <string.h>

// 动态数组接口
CArray carray_create(size_t size) {
    if (size == 0) return NULL;
    return (CArray)int_array_create(size);
}

void carray_free(CArray arr) {
    if (arr) {
        int_array_free((IntArray*)arr);
    }
}

void carray_append(CArray arr, int32_t value) {
    if (!arr) return;
    int_array_push((IntArray*)arr, value);
}

int32_t carray_get(CArray arr, size_t index) {
    if (!arr) return 0;
    return int_array_get((IntArray*)arr, index);
}

size_t carray_size(CArray arr) {
    if (!arr) return 0;
    return ((IntArray*)arr)->size;
}

// 矩阵接口
CMatrix cmatrix_create(size_t rows, size_t cols) {
    if (rows == 0 || cols == 0) return NULL;
    return (CMatrix)matrix_create(rows, cols);
}

void cmatrix_free(CMatrix mat) {
    if (mat) {
        matrix_free((Matrix*)mat);
    }
}

ErrorCode cmatrix_set(CMatrix mat, size_t row, size_t col, double value) {
    if (!mat) return ERR_NULL_PTR;
    Matrix* matrix = (Matrix*)mat;
    if (row >= matrix->rows || col >= matrix->cols) 
        return ERR_INDEX_OUT_OF_RANGE;
    
    matrix->data[row * matrix->cols + col] = value;
    return SUCCESS;
}

double cmatrix_get(CMatrix mat, size_t row, size_t col) {
    if (!mat) return 0.0;
    Matrix* matrix = (Matrix*)mat;
    if (row >= matrix->rows || col >= matrix->cols) 
        return 0.0;
    
    return matrix->data[row * matrix->cols + col];
}

CMatrix cmatrix_multiply(CMatrix a, CMatrix b, ErrorCode* error) {
    if (!a || !b) {
        if (error) *error = ERR_NULL_PTR;
        return NULL;
    }
    
    Matrix* result = NULL;
    ErrorCode err = matrix_multiply((Matrix*)a, (Matrix*)b, &result);
    
    if (error) *error = err;
    return (CMatrix)result;
}

// 图像接口
CImage cimage_create(size_t width, size_t height, int channels) {
    if (width == 0 || height == 0 || channels == 0) return NULL;
    return (CImage)image_create(width, height, channels);
}

void cimage_free(CImage img) {
    if (img) {
        image_free((Image*)img);
    }
}

ErrorCode cimage_set_pixel(CImage img, size_t x, size_t y, uint8_t r, uint8_t g, uint8_t b) {
    if (!img) return ERR_NULL_PTR;
    Image* image = (Image*)img;
    
    if (x >= image->width || y >= image->height)
        return ERR_INDEX_OUT_OF_RANGE;
    
    if (image->channels < 3)
        return ERR_INVALID_CHANNELS;
    
    size_t index = (y * image->width + x) * image->channels;
    image->data[index] = r;
    image->data[index+1] = g;
    image->data[index+2] = b;
    
    return SUCCESS;
}

ErrorCode cimage_get_pixel(CImage img, size_t x, size_t y, uint8_t* r, uint8_t* g, uint8_t* b) {
    if (!img || !r || !g || !b) return ERR_NULL_PTR;
    Image* image = (Image*)img;
    
    if (x >= image->width || y >= image->height)
        return ERR_INDEX_OUT_OF_RANGE;
    
    if (image->channels < 3)
        return ERR_INVALID_CHANNELS;
    
    size_t index = (y * image->width + x) * image->channels;
    *r = image->data[index];
    *g = image->data[index+1];
    *b = image->data[index+2];
    
    return SUCCESS;
}

CImage cimage_grayscale(CImage img, ErrorCode* error) {
    if (!img) {
        if (error) *error = ERR_NULL_PTR;
        return NULL;
    }
    
    Image* gray = NULL;
    ErrorCode err = image_grayscale((Image*)img, &gray);
    
    if (error) *error = err;
    return (CImage)gray;
}